package com.future.base;

import java.io.Serializable;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.future.common.ReflectionUtils;

public class BaseHibernateDao<T, PK extends Serializable>
{
	protected Logger logger = LoggerFactory.getLogger(getClass());
	@Resource
	private SessionFactory sessionFactory;
	
	private Class<T> entityClass;
	
	public Session getSession(){
		return sessionFactory.getCurrentSession();
	}
	
	/**
	 * 保存或更新
	 * @autor wanghongkai
	 * @param entity
	 */
	public void saveOrUpdate(BaseEntity entity){
		Assert.notNull(entity, "entity不能为空");
		getSession().saveOrUpdate(entity);
	}
	
	/**
	 * 物理删除
	 * @autor wanghongkai
	 * @param entity
	 */
	public void delete(BaseEntity entity){
		Assert.notNull(entity, "entity不能为空");
		getSession().delete(entity);
	}
	
	@SuppressWarnings("unchecked")
	public T findUnique(final PK id){
		Assert.notNull(id,"id 不能为null");
		return (T) getSession().get(entityClass, id);
	}
	
	/**
	 * 用于Dao层子类使用的构造函数.
	 * 通过子类的泛型定义取得对象类型Class.
	 * eg.
	 * public class UserDao extends SimpleHibernateDao<User, Long>
	 */
	public BaseHibernateDao() {
		this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
	}

	/**
	 * 用于用于省略Dao层, 在Service层直接使用通用SimpleHibernateDao的构造函数.
	 * 在构造函数中定义对象类型Class.
	 * eg.
	 * SimpleHibernateDao<User, Long> userDao = new SimpleHibernateDao<User, Long>(sessionFactory, User.class);
	 */
	public BaseHibernateDao(final SessionFactory sessionFactory, final Class<T> entityClass) {
		this.sessionFactory = sessionFactory;
		this.entityClass = entityClass;
	}
}
